# akshare_finance/analyzer.py
from typing import List, Dict, Any, Optional
import pandas as pd
import numpy as np

class FinancialDataAnalyzer:
    """财务数据分析器，简化版"""
    
    def __init__(self, metrics: List[str], time_periods: List[str]) -> None:
        self.metrics = metrics
        self.time_periods = time_periods

    def analyze_financial_abstract(self, df: pd.DataFrame) -> pd.DataFrame:
        """分析财务摘要数据，筛选指定指标和时间段"""
        if df is None or df.empty:
            return pd.DataFrame()
            
        df = df.copy()
        df.columns = [str(c).strip() for c in df.columns]
        
        # 检查数据格式
        if "指标" in df.columns:
            # 新浪财经格式：行是指标，列是时间
            return self._analyze_sina_format(df)
        elif "报告期" in df.columns or "REPORT_DATE" in df.columns:
            # 同花顺格式或东方财富格式：行是时间，列是指标
            return self._analyze_em_format(df)
        else:
            # 尝试查找指标列
            for col in df.columns:
                if "指标" in str(col):
                    df.rename(columns={col: "指标"}, inplace=True)
                    return self._analyze_sina_format(df)
            return pd.DataFrame()

    def _analyze_sina_format(self, df: pd.DataFrame) -> pd.DataFrame:
        """处理新浪财经格式的数据"""
        # 筛选指定指标
        mask = df["指标"].isin(self.metrics)
        
        # 确定可用列
        available_cols = ["指标"] + [col for col in self.time_periods if col in df.columns]
        
        if len(available_cols) <= 1:  # 只有指标列，没有数据列
            return pd.DataFrame()
            
        result = df.loc[mask, available_cols].drop_duplicates().reset_index(drop=True)
        return result
    
    def _analyze_ths_format(self, df: pd.DataFrame) -> pd.DataFrame:
        """处理同花顺格式的数据"""
        # 筛选指定指标列
        available_metrics = [col for col in self.metrics if col in df.columns]
        
        if not available_metrics:
            return pd.DataFrame()
        
        # 筛选指定时间期间行
        if self.time_periods:
            # 转换报告期为字符串便于比较
            df['报告期_str'] = df['报告期'].astype(str)
            time_mask = df['报告期_str'].isin([str(p) for p in self.time_periods])
            if time_mask.any():
                filtered_df = df.loc[time_mask]
            else:
                # 如果没有完全匹配，取最新的几期数据
                filtered_df = df.head(min(len(self.time_periods), len(df)))
        else:
            filtered_df = df
        
        # 选择需要的列
        result_cols = ["报告期"] + available_metrics
        result = filtered_df[result_cols].copy()
        
        # 转换为新浪格式以保持兼容性（行是指标，列是时间）
        return self._convert_ths_to_sina_format(result)
    
    def _convert_ths_to_sina_format(self, df: pd.DataFrame) -> pd.DataFrame:
        """将同花顺格式转换为新浪格式"""
        if df.empty or "报告期" not in df.columns:
            return pd.DataFrame()
        
        # 转置数据：行变成列，列变成行
        df_transposed = df.set_index("报告期").T
        df_transposed.index.name = "指标"
        df_transposed.reset_index(inplace=True)
        
        # 重新排列列的顺序，最新日期在前
        date_cols = [col for col in df_transposed.columns if col != "指标"]
        date_cols_sorted = sorted(date_cols, reverse=True)  # 降序排列，最新在前
        
        result_cols = ["指标"] + date_cols_sorted
        result = df_transposed[result_cols].copy()
        
        return result
    
    def _analyze_em_format(self, df: pd.DataFrame) -> pd.DataFrame:
        """处理东方财富格式的数据 (REPORT_DATE列，指标为列名)"""
        # 东方财富API指标映射 
        em_metric_mapping = {
            'ROEJQ': '净资产收益率',
            'XSJLL': '销售净利率', 
            'TOAZZL': '总资产周转率',
            'ZCFZL': '资产负债率',
            'QYCS': '权益乘数',
            'TOTALOPERATEREVE': '营业总收入',
            'PARENTNETPROFIT': '净利润',
            'ZZCJLL': '总资产净利率',
            'MLR': '毛利率'
        }
        
        # 选择可用的指标列
        available_em_cols = [col for col in em_metric_mapping.keys() if col in df.columns]
        if not available_em_cols:
            return pd.DataFrame()
        
        # 确定时间列
        time_col = 'REPORT_DATE' if 'REPORT_DATE' in df.columns else '报告期'
        
        # 筛选指定时间期间
        if self.time_periods:
            # 转换时间期间格式以便匹配
            df['date_str'] = pd.to_datetime(df[time_col]).dt.strftime('%Y%m%d')
            time_mask = df['date_str'].isin(self.time_periods)
            if time_mask.any():
                filtered_df = df.loc[time_mask]
            else:
                # 如果没有完全匹配，取最新的几期数据
                filtered_df = df.head(min(len(self.time_periods), len(df)))
        else:
            filtered_df = df.head(10)  # 默认取前10期
        
        # 选择需要的列
        result_cols = [time_col] + available_em_cols
        result = filtered_df[result_cols].copy()
        
        # 重命名列名为中文
        rename_dict = {time_col: '报告期'}
        rename_dict.update({col: em_metric_mapping[col] for col in available_em_cols})
        result.rename(columns=rename_dict, inplace=True)
        
        # 转换为标准格式（行是指标，列是时间）
        return self._convert_em_to_sina_format(result)
    
    def _convert_em_to_sina_format(self, df: pd.DataFrame) -> pd.DataFrame:
        """将东方财富格式转换为新浪格式"""
        if df.empty or "报告期" not in df.columns:
            return pd.DataFrame()
        
        # 格式化报告期为字符串
        df['报告期'] = pd.to_datetime(df['报告期']).dt.strftime('%Y%m%d')
        
        # 转置数据：行变成列，列变成行
        df_transposed = df.set_index("报告期").T
        df_transposed.index.name = "指标"
        df_transposed.reset_index(inplace=True)
        
        # 重新排列列的顺序，最新日期在前
        date_cols = [col for col in df_transposed.columns if col != "指标"]
        date_cols_sorted = sorted(date_cols, reverse=True)  # 降序排列，最新在前
        
        result_cols = ["指标"] + date_cols_sorted
        result = df_transposed[result_cols].copy()
        
        return result

    @staticmethod
    def _to_numeric(series: pd.Series) -> pd.Series:
        """安全转换为数值"""
        return pd.to_numeric(
            series.astype(str).str.replace("%", "").str.replace(",", ""), 
            errors="coerce"
        )

    def calculate_sector_statistics(self, companies_data: Dict[str, Optional[pd.DataFrame]]) -> pd.DataFrame:
        """计算板块统计数据"""
        if not companies_data:
            return pd.DataFrame()
            
        # 收集所有公司的最新数据
        all_latest_data = []
        
        for company_name, financial_df in companies_data.items():
            if financial_df is None or financial_df.empty:
                continue
                
            company_latest = self._extract_latest_values(financial_df)
            if not company_latest.empty:
                company_latest["公司"] = company_name
                all_latest_data.append(company_latest)
        
        if not all_latest_data:
            return pd.DataFrame()
            
        # 合并所有数据
        combined_df = pd.concat(all_latest_data, ignore_index=True)
        
        # 按指标分组计算统计量
        stats_data = []
        for metric in self.metrics:
            metric_data = combined_df[combined_df["指标"] == metric]["数值"]
            if metric_data.empty:
                continue
                
            stats = {
                "指标": metric,
                "样本数": len(metric_data),
                "均值": metric_data.mean(),
                "中位数": metric_data.median(),
                "标准差": metric_data.std(),
                "最小值": metric_data.min(),
                "最大值": metric_data.max(),
                "25%分位": metric_data.quantile(0.25),
                "75%分位": metric_data.quantile(0.75)
            }
            stats_data.append(stats)
        
        return pd.DataFrame(stats_data)

    def _extract_latest_values(self, financial_df: pd.DataFrame) -> pd.DataFrame:
        """提取每个指标的最新可用值"""
        if financial_df.empty:
            return pd.DataFrame()
            
        results = []
        for _, row in financial_df.iterrows():
            metric = row.get("指标")
            if pd.isna(metric):
                continue
                
            # 寻找最近的非空值
            for period in self.time_periods:
                if period in row.index and pd.notna(row[period]):
                    value = self._to_numeric(pd.Series([row[period]])).iloc[0]
                    if pd.notna(value):
                        results.append({
                            "指标": metric,
                            "期间": period,
                            "数值": float(value)
                        })
                        break
        
        return pd.DataFrame(results)
    
    def analyze_company_financial_abstract(self, company: Dict[str, str]) -> Optional[pd.DataFrame]:
        """分析单个公司的财务摘要（新增方法）"""
        # 这个方法是为了与管道兼容，实际逻辑在analyze_financial_abstract中处理
        return None